クラウドHA-WAFパターン:SOPHOS UTM9 on Amazon VPCで高可用性のWAFを構築
そろそろマニアック過ぎて、誰もついて来ていない気がしていますw 10ブクマいったら拍手喝采。
今回のエントリーは、下記の2つのエントリーが伏線となっています。まだお読みでない方は、先に下記エントリをご覧下さい。
お気づきでしょうか、UTM9もEC2インスタンスに乗っているコンポーネントであるため、前回ご紹介した「単純にUTM9を配置する構成」の場合、UTMサーバがSPOF(単一障害点)となってしまいます。そこで今回は、SOPHOS UTM9を高可用性(HA)の構成にしてみようと思います。前回のUTM9の構成は、簡略化のために非VPC構成で構築しました。が、今回はより本格的に、VPC上に組み立てていこうと思います。
システム概要
図をご覧下さい。以上。
としたいところですが、一応解説。
このシステムはELBを2段で噛ましてます。ユーザは1つ目(上: ha-lbext)のELBにアクセスし、複数AZにまたがった「UTMサーバ」にアクセスを振り分けます。UTM9の「本サーバ」には、2つ目(下: ha-lbint)のELBを設定しておき、リクエストが転送されます。この2つ目のELBは「内部ロードバランサ」と呼ばれ、グローバルIPアドレスを持たない、VPC内で利用するロードバランサです。この内部ロードバランサを介して「Webコンテンツサーバ」にリクエストが到達します。2つ目の「内部LB」に対して、1つ目のELBのことは、本エントリーでは「外部LB」と呼ぶことにします。
以上がメインとなる経路です。あとはNATや踏み台サーバを置くか置かないか等によって構成が変わってきます。
上側2つのサブネットには外部LBを配置するため、public-subnetとなるのは確定です。更なる堅牢性を要求するのであれば、外部LBとUTMサーバのサブネットを分けてもいいかもしれません。
下側2つについては、httpd等のインストールのためにyumを使うタイミングがあります。これらを、より堅牢な構成としてprotected-subnet(private-subnate w/NAT)とする場合は、public-subnet側にNATを配置する必要があります。UTMを配置するほどの要件であれば、protected-subnetとすべきでしょう。
ただ、今回はチュートリアル目的であるため、全てのサブネットをpublic-subnetとして構築することにします。
先のエントリーで指摘している通り、UTMサーバは一定のメモリが必要なためm1.smallで立ち上げます。Webコンテンツサーバはt1.microでいきましょう。
システム構築
さて、上記構成を作っていきましょう。そこそこ複雑な構成であるため、先に全体の流れを把握しておきましょう。下記8ステップの作業になります。
- VPCの作成
- Subnetの作成
- Security Groupの作成
- Webコンテンツサーバの構築
- 内部LBの構築
- UTMサーバの起動
- 外部LBの構築
- UTMサーバの設定
1及び2については、「Amazon VPCを使ったミニマム構成のサーバ環境を構築する」を参考にして構築してください。VPC Wizardを利用しても構いません。全てのsubnetに同じRouteTable(public-subnetのため、InternetGatewayが設定されている)を割り当てればOKですね。
以下では、3以降を解説します。
3. Security Groupの作成
全体像としてはこんな感じです。もしSecurity Groupの設定に自身がなければ、VPC内同士の通信許可としてdefaultグループを使っても良いでしょう。
- secg-lbext : 外部LB用。全IPからtcp/80にアクセスできる。
- secg-utm : UTMサーバ用。secg-lbextからtcp/80にアクセスできる。全IPからtcp/4444にアクセスできる。
- secg-lbint : 内部LB用。secg-utmからtcp/80にアクセスできる。
- secg-web : Webコンテンツサーバ用。secg-lbintからtcp/80にアクセスできる。全IPからtcp/22にアクセスできる。
(スクリーンショット撮り忘れましたw
「80(HTTP) -> sg-6e******」
「22(SSH) -> 0.0.0.0/0」
となります。)
4. Webコンテンツサーバの構築
普通に、Amazon Linux 64bitの最新版を、下側の2つのサブネットに各1つ作成し、それぞれ ha-web-leftとha-web-rightと名付けます。起動先のサブネットを分ける必要があるので、一気に2台作成することはできません。Secutiry Groupはどちらものsecg-webを割り当てましょう。これらのインスタンスには一時的にEIPを振り、SSHでログインします。httpdをインストール&起動し、index.htmlにそれぞれのサーバが認識できるような内容を書き込みます。念のためcurlでアクセスしてみると、index.htmlの内容が取れるはずです。
$ sudo yum -y install httpd $ sudo service httpd start $ sudo sh -c 'echo "<html><body>ha-web-left</body></html>" >>/var/www/html/index.html' $ curl http://localhost <html><body>ha-web-left</body></html>
HTMLの内容について、2台目はleftではなくrightにしましょうね。慣れている方は、わざわざSSHでログインせずに、User Dataにシェルスクリプトを組み込んでしまえば良いと思います。(ただし、EIPは後の検証のために必須です。)
参考: Amazon EC2のUser Dataにシバンを指定してスクリプトを実行する
5. 内部LBの構築
EC2のManagement Consoleの左側メニューから「Load Balancers」を選択し、Create Load Balancerボタンをクリックします。
ELBの名前として「ha-lbint」を設定し、先ほど作成したVPCを指定します。また「Create an internal load balancer」のチェックボックスをONにするのを忘れないでください。その他はデフォルトで構いません。
この画面はデフォルトのままでも構いませんし、検証をやりやすくするため、Health Check Intervalを0.1秒に、Healthy Thresholdを2にしても構いません。
ELB配置先のサブネットは、10.0.20.0/24 と 10.0.21.0/24 を選択。
Security Groupとして、先ほど作成した secg-lbint を指定します。しかし、ここでsecg-lbintがデフォルトで自動選択されているのは、さりげなくManagement Consoleが凝っているところだと思いませんか? よく空気を読んでくれています。
内部LB配下に、2つのWebコンテンツサーバを編入します。
以上で内部LBの設定を完了させてください。完了してしばらくすると、ステータスが「2 of 2 instances in service」となるはずです。
6. UTMサーバの起動
引き続き、UTMサーバの構築に移ります。以下の作業も、ほぼ同じ作業を2回繰り返す必要があります。それぞれを ha-utm-leftとha-utm-rightと名付けます。起動先のサブネットを分ける必要があるので、一気に2台作成することはできません。
AWS MarketplaceにおけるUTM9のページより、UTMサーバを作成します。Continueボタンをクリックして次のページへ。前回は「1-Click Launch」で起動しましたが、今回はVPC内に起動しなければならないため、「Launch with EC2 Console」側のタブを選択し、適切なリージョン(本エントリの検証ではus-east-1を利用しています)の「Launch with EC2 Console」ボタンをクリックします。
起動するAMIやアーキテクチャ等の確認。特に設定項目はありません。
サブネットを適切に選択(1度目は10.0.10.0/24、2度目は10.0.11.0/24)し、インスタンスタイプを m1.small に設定します。
扱いやすいように、IPアドレスを自動割り当てせず、明示的に指定しておきます。
あとはKeyPairは適切に、SecurityGroupは secg-utm を指定し、起動します。これらの2台についても、メンテナンスのためEIPを振っておいてください。 https://(UTMサーバのEIP):4444/ でUTM9のコンソールにアクセスできます。(HTTPSであることに注意!)
ここまでの設定で、EC2インスタンスはこんな感じになっているはずです。
7. 外部LBの構築
続いて、外部LBの構築を行います。先ほどの内部LBとほぼ同様です。ただし、「Create an internal load balancer」のチェックボックスはOFFにしておきます。
ELB配置先のサブネットは、10.0.10.0/24 と 10.0.11.0/24 を選択。
その他、SecurityGroupは ha-lbext を選択。ELB配下に編入するインスタンスは先ほど起動した2台のUTMサーバですね。
以上で、外部LBの構築は完了です。完了してしばらくすると、ステータスが「2 of 2 instances in service」となるはずです。
8. UTMサーバの設定
さああと一息。UTM9の設定を2台分。ほぼ同じ作業を ha-utm-left 及び ha-utm-right に対して行ってください。コンソールへURLは https://(UTMサーバのEIP):4444/ (HTTPSであることに注意!)でしたね。初回設定は以下の通り。Hostnameの所には、プライベートのIPアドレスを入れておきましょう。
以下は、以前のエントリを参考にしてください。タイムゾーンや言語の設定もやってしまいましょう。
WAFの「本サーバ」として、内部LBのドメイン名を設定します。
WAFの「仮想サーバ」として、外部LBのドメイン名を設定します。
最後に、WAFを有効化して完了です。おつかれさまでした。書いてる方もちょっと疲れましたw
検証
まず、ブラウザで、外部LBにアクセスしてみてください。UTMサーバを介して、コンテンツサーバのレスポンスが表示されることを確認しましょう。リロードを繰り返すと、left と right それぞれが等確率で表示されるはずです。
次に、Webコンテンツサーバの模擬障害によるフェイルオーバーを試します。例えばha-web-rightにSSHログインし、httpdをstopしてみます。その上で外部LBを開いたブラウザをリロードすると、ha-web-leftのみが表示されるようになります。
続いて、UTMサーバの模擬障害によるフェイルオーバーを試します。ha-utm-leftのWAF機能を、Disableボタンによって停止(左のブラウザが赤信号)させてみます。その上で外部LBを開いたブラウザにリロードを掛けても、サービスが継続していることが分かります。
そして、ha-utm-leftの模擬障害は一旦復旧させます。そして今度は ha-utm-right をDisableにしてみても、同様にサービスは継続しています。
最後に、起こってはならないことですが、両方のWAFが死んでしまった場合を一応確認しておきましょう。まぁ、想定通り、お亡くなりになりました。
まとめ
さて、長くなってしまいましたが。AWSの本番運用には、Availability Zoneを活用したHA構成が必須です。WAF等の機構を導入する際は、コンテンツサーバだけでなく、そのWAF自体にもHAの構成が必要になってきます。今回は Sophos UTM9 を利用して、その実例を示してみました。